from django.shortcuts import render
from django.views import View
from django import http
from django_redis import get_redis_connection
import json
import pickle
import base64

from goods.models import SKU

# Create your views here.


class CartsSimpleView(View):
    def get(self, request):
        if request.user.is_authenticated:
            # 用户已登录
            conn = get_redis_connection('carts')
            # data: {b'sku_id': b'count', ....}
            data = conn.hgetall('carts_%s' % request.user.id)
            selected_ids = conn.smembers('selected_%s' % request.user.id)
            # 第一种方法
            # sku_ids = data.keys()
            # skus = SKU.objects.filter(id__in=selected_ids)
            # cart_skus = []
            # for sku in skus:
            #     cart_skus.append({
            #         'id': sku.id,
            #         'name': sku.name,
            #         # str(sku.id).encode()-->b'1'   sku.id.encode()-->b'08/29/'
            #         'count': int(data[str(sku.id).encode()]),
            #         'default_image_url': sku.default_image_url
            #     })

            # 第二种方法
            cart_dict = {}
            for sku_id, count in data.items():
                cart_dict[int(sku_id)] = {
                    'count': int(count),
                    'selected': sku_id in selected_ids
                }
        else:
            # 用户未登录
            cookie_cart = request.COOKIES.get('carts')
            if cookie_cart:
                # cart_dict:{'sku_id':{'count': 5, 'selected': 'ture'}}
                cart_dict = pickle.loads(base64.b64decode(cookie_cart))
            else:
                cart_dict = {}
        sku_ids = cart_dict.keys()
        skus = SKU.objects.filter(id__in=sku_ids)
        cart_skus = []
        for sku in skus:
            if cart_dict[sku.id]['selected']:
                cart_skus.append({
                    'id': sku.id,
                    'name': sku.name,
                    'count': cart_dict[sku.id]['count'],
                    'default_image_url': sku.default_image_url
                })

        return http.JsonResponse({'code': 0, 'errmsg': 'ok', 'cart_skus': cart_skus})


class CartSelectAllView(View):
    """全选购物车"""
    def put(self, request):
        # 提取参数
        json_dict = json.loads(request.body.decode())
        selected = json_dict.get('selected')

        # 校验参数
        if not isinstance(selected, bool):
            return http.JsonResponse({'code': 400, 'errmsg': '参数无效'})

        if request.user.is_authenticated:
            # 用户已登录
            conn = get_redis_connection('carts')
            data = conn.hgetall('carts_%s' % request.user.id)
            sku_ids = data.keys()
            # for sku_id in sku_ids:
            if selected:
                conn.sadd('selected_%s' % request.user.id, *sku_ids)
            else:
                conn.srem('selected_%s' % request.user.id, *sku_ids)
            return http.JsonResponse({'code': 0, 'errmsg': 'ok'})
        else:
            # 用户未登录
            cookie_cart = request.COOKIES.get('carts')
            if cookie_cart:
                cart_dict = pickle.loads(base64.b64decode(cookie_cart))
            else:
                cart_dict = {}
            sku_ids = cart_dict.keys()
            for sku_id in sku_ids:
                cart_dict[sku_id]['selected'] = selected

            data = base64.b64encode(pickle.dumps(cart_dict)).decode()
            response = http.JsonResponse({'code': 0, 'errmsg': 'ok'})
            response.set_cookie('carts', data)
            return response


class CartsView(View):
    def delete(self, request):
        """删除购物车数据"""
        json_dict = json.loads(request.body.decode())
        sku_id = json_dict.get('sku_id')
        if not isinstance(sku_id, int):
            return http.JsonResponse({'code': 0, 'errmsg': '参数有误'})

        if request.user.is_authenticated:
            # 用户已登录
            conn = get_redis_connection('carts')
            conn.hdel('carts_%s' % request.user.id, sku_id)
            conn.srem('selected_%s' % request.user.id, sku_id)
            return http.JsonResponse({'code': 0, 'errmsg': 'ok'})
        else:
            # 用户未登录
            cookie_cart = request.COOKIES.get('carts')
            if cookie_cart:
                cart_dict = pickle.loads(base64.b64decode(cookie_cart))
            else:
                cart_dict = {}

            del cart_dict[sku_id]
            data = base64.b64encode(pickle.dumps(cart_dict)).decode()
            response = http.JsonResponse({'code': 0, 'errmsg': 'ok'})
            response.set_cookie('carts', data)
            return response

    def put(self, request):
        """修改购物车数据"""
        # 提取参数
        json_dict = json.loads(request.body.decode())
        sku_id = json_dict.get('sku_id')
        count = json_dict.get('count')
        selected = json_dict.get('selected')
        # 校验参数
        if not all([sku_id, count]):
            return http.JsonResponse({'code': 400, 'errmsg': '缺少参数'})

        if isinstance(sku_id, str) and not sku_id.isdigit():
            return http.JsonResponse({'code': 400, 'errmsg': 'sku_id参数有误'})

        if isinstance(count, str) and not count.isdigit():
            return http.JsonResponse({'code': 400, 'errmsg': 'sku_id参数有误'})

        if selected:
            if not isinstance(selected, bool):
                return http.JsonResponse({'code': 400, 'errmsg': 'sku_id参数有误'})

        if request.user.is_authenticated:
            # 用户已登录
            conn = get_redis_connection('carts')
            pl = conn.pipeline()

            # 写入修改数据
            pl.hset('carts_%s' % request.user.id, sku_id, count)
            if selected:
                pl.sadd('selected_%s' % request.user.id, sku_id)
            else:
                pl.srem('selected_%s' % request.user.id, sku_id)
            # 执行管道
            pl.execute()
            cart_sku = {
                'id': sku_id,
                'count': int(count),
                'selected': selected
            }
            return http.JsonResponse({'code': 0, 'errmsg': 'ok', 'cart_sku': cart_sku})

        else:
            # 用户未登录
            # {'14':{'count':5, 'selected':true}}
            cookie_cart = request.COOKIES.get('carts')
            if cookie_cart:
                cart_dict = pickle.loads(base64.b64decode(cookie_cart))
            else:
                cart_dict = {}
            cart_dict[sku_id] = {'count': count, 'selected': selected}
            cart_sku = {
                'id': sku_id,
                'count': count,
                'selected': selected
            }
            response = http.JsonResponse({'code': 0, 'errmsg': 'ok', 'cart_sku': cart_sku})
            data = base64.b64encode(pickle.dumps(cart_dict)).decode()
            # cookie只能传字符串
            response.set_cookie('carts', data)

            return response

    def get(self, request):
        """展示购物车数据"""
        if request.user.is_authenticated:
            conn = get_redis_connection('carts')
            # data是字典 {b'15': b'1', b'12': b'5'}
            data = conn.hgetall('carts_%s' % request.user.id)
            selected = conn.smembers('selected_%s' % request.user.id)
            cart_skus = []
            # print(data.items())
            for sku_id, count in data.items():
                sku = SKU.objects.get(id=int(sku_id))
                # sku = SKU.objects.get(id=sku_id)
                cart_skus.append({
                    'id': sku.id,
                    'name': sku.name,
                    'count': int(count),
                    'selected': sku_id in selected,
                    'default_image_url': sku.default_image_url,
                    'price': sku.price,
                    'mount': sku.price * int(count)
                })

            # return http.JsonResponse({'code': 0, 'errmsg': 'ok', 'cart_skus': cart_skus})

        else:
            # 未登录
            cookie_cart = request.COOKIES.get('carts')
            # cart_dict={'14':{'count': 1, 'selected': True}}

            if cookie_cart:
                cart_dict = pickle.loads(base64.b64decode(cookie_cart))
            else:
                cart_dict = {}
            sku_ids = cart_dict.keys()
            cart_skus = []
            for sku_id in sku_ids:
                sku = SKU.objects.get(id=sku_id)
                cart_skus.append({
                    'id': sku.id,
                    'name': sku.name,
                    'count': cart_dict[sku_id]['count'],
                    'selected': cart_dict[sku_id]['selected'],
                    'default_image_url': sku.default_image_url,
                    'price': sku.price,
                    'mount': sku.price * cart_dict[sku_id]['count']
                })

        return http.JsonResponse({'code': 0, 'errmsg': 'ok', 'cart_skus': cart_skus})

    def post(self, request):
        """添加购物车数据"""
        # 提取参数
        json_dict = json.loads(request.body.decode())
        sku_id = json_dict.get('sku_id')
        count = json_dict.get('count')
        selected = json_dict.get('selected', True)

        # 校验参数
        if not all([sku_id, count]):
            return http.JsonResponse({'code': 400, 'errmsg': '缺少参数'})

        if isinstance(sku_id, str) and not sku_id.isdigit():
            return http.JsonResponse({'code': 400, 'errmsg': 'sku_id参数有误'})

        if isinstance(count, str) and not count.isdigit():
            return http.JsonResponse({'code': 400, 'errmsg': 'sku_id参数有误'})

        if selected:
            if not isinstance(selected, bool):
                return http.JsonResponse({'code': 400, 'errmsg': 'selected参数有误'})

        # 数据处理
        if request.user.is_authenticated:
            # 1.1 用户登录
            conn = get_redis_connection('carts')
            pl = conn.pipeline()
            # hincrby数据存在自增,不存在就添加
            pl.hincrby('carts_%s' % request.user.id, sku_id, count)
            if selected:
                pl.sadd('selected_%s' % request.user.id, sku_id)
            pl.execute()
            return http.JsonResponse({'code': 0, 'errmsg': 'ok'})

        else:
            # 1.2 用户未登录, 把购物车的数据存到cookie里面
            cookie_cart = request.COOKIES.get('carts')
            # if cookie_data:
            # 把cookie_data进行解码
            # 字典数据类型{'14': {'count': 1, 'selected': 2}}
            if cookie_cart:
                cart_dict = pickle.loads(base64.b64decode(cookie_cart))

            else:
                cart_dict = {}

            if sku_id in cart_dict.keys():
                cart_dict[sku_id]['count'] += count
                cart_dict[sku_id]['selected'] = selected

            else:
                # cart_dict[sku_id]['count'] = count
                # cart_dict[sku_id]['selected'] = selected
                cart_dict[sku_id] = {
                    'count': count,
                    'selected': selected
                }

            data = base64.b64encode(pickle.dumps(cart_dict)).decode()
            response = http.JsonResponse({'code': 0, 'errmsg': 'ok'})
            response.set_cookie('carts', data)
            return response




